import CryptoJS from "crypto-js";
import SparkMD5 from "spark-md5";
import JsEncrypt from "jsencrypt";

/** 加解密模块 */
export class CryptHelper {

  private keyId: string;
  private readonly publicKey: string;

  constructor(keyId: string, publicKey: string) {
    this.keyId = keyId;
    this.publicKey = publicKey;
  }

  sortParam(data: any): string {
    let keys = Object.keys(data);
    keys.sort(function(x, y) {
      if (x > y) {
        return 1;
      }
      return -1;
    });
    let paramArr = [];
    for (let k of keys) {
      paramArr.push(k + "=" + data[k]);
    }
    paramArr.push("key=5b8af47892d636624dde271aa5e19938");
    return paramArr.join("&");
  }

  signData(data: any) {
    let spark = new SparkMD5();
    return spark.append(this.sortParam(data)).end();
  }

  /** 生成n位随机 32 进制字符串 */
  randomKeys(): string {
    const charList = "ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678";
    let str = "", len = charList.length;
    for (let i = 0; i < 32; i++) {
      str += charList[Math.floor(Math.random() * len)];
    }
    return str;
  }

  /**
   * AES加密原始数据
   */
  aesEncrypt(keyWord: string, word: string): string | null {
    if (keyWord.length !== 16 && keyWord.length !== 32) {
      console.error("密钥必须是16位或32位");
      return null;
    }
    const key = CryptoJS.enc.Utf8.parse(keyWord);
    const src = CryptoJS.enc.Utf8.parse(word);
    const encrypted = CryptoJS.AES.encrypt(src, key, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    });
    return encrypted.toString();

  }

  /**
   * AES解密加密的json数据
   */
  aesDecrypt(keyWord: string, word: string): string | null {
    if (keyWord.length !== 16 && keyWord.length !== 32) {
      console.error("密钥必须是16位或32位");
      return null;
    }
    const key = CryptoJS.enc.Utf8.parse(keyWord);
    const decrypt = CryptoJS.AES.decrypt(word, key, {
      mode: CryptoJS.mode.ECB,
      padding: CryptoJS.pad.Pkcs7,
    });
    return CryptoJS.enc.Utf8.stringify(decrypt).toString();
  }

  /**
   * rsa算法公钥加密
   * @param params
   */
  rsaEncrypt(params: object | string): string | false {
    const Encrypt = new JsEncrypt();
    Encrypt.setPublicKey(this.publicKey);
    return Encrypt.encrypt(
      typeof params === "object" ? JSON.stringify(params) : params,
    );
  }

}



